[paper_trail](https://github.com/airblade/paper_trail) is a gem used for auditing and versioning your models. We can easily use it with active_admin to show a list of recently modified items in the admin screen.

Example:

![](http://i.imgur.com/q6LGP.png)

## Integration instructions

1. Install PaperTrail as a gem via your `Gemfile`:

    `gem 'paper_trail'`

2. Generate a migration which will add a `versions` table to your database:

    `rails generate paper_trail:install`

3. Run the migration:

    `rake db:migrate`

4. Add `user_for_paper_trail` to controller so paper_trail knows which user updated the item and the `before_action :set_paper_trail_whodunnit` (see https://git.io/vrTsk why you need to do this). (optional)

```ruby
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_paper_trail_whodunnit

  # ...
  protected

  def user_for_paper_trail
    admin_user_signed_in? ? current_admin_user.try(:id) : 'Unknown user'
  end
  # ...
end
```

5. Add `has_paper_trail` to the models you want to track:

```ruby
# app/models/post.rb
class Post < ActiveRecord::Base
  has_paper_trail
  # ...
end
```

6. Display the versions table on the dashboard

```ruby
# app/admin/dashboard.rb
section "Recently updated content" do
  table_for PaperTrail::Version.order(id: :desc).limit(20) do # Use PaperTrail::Version if this throws an error
    column ("Item") { |v| v.item_id }
    # column ("Item") { |v| link_to v.item, [:admin, v.item] } # Uncomment to display as link
    column ("Type") { |v| v.item_type.underscore.humanize }
    column ("Modified at") { |v| v.created_at.to_s :long }
    column ("Admin") { |v| link_to AdminUser.find(v.whodunnit).email, [:admin, AdminUser.find(v.whodunnit)] }
  end
end
```

### Linking to model

To link the `item` column to your model in active_admin use:

```ruby
column ("Item") do |v| 
  if v.item
    link_to v.item, [:admin, v.item]
  end
end
```

### Versioning models

in `app/admin/posts.rb`:

```ruby
ActiveAdmin.register Post do
  sidebar :versionate, :partial => "layouts/version", :only => :show

  controller do
    def show
      @post = Post.includes(versions: :item).find(params[:id])
      @versions = @post.versions 
      @post = @post.versions[params[:version].to_i].reify if params[:version]
      show! #it seems to need this
    end
  end
end
```
then create the partial in `app/views/layouts/_version.html.erb` with this:

```erb
<% if !@versions.empty? %>
  <h3>Current Version: <%= @versions.length %></h3>

  <b>Created At:</b>
  <%= @versions.last.created_at%>
  <br>
  <b>Admin</b>: <%= AdminUser.find(@versions.last.whodunnit).email %>
  <br>
  <% if @versions.length.to_i > 1 %>
    <% if params[:version].to_i > 1 || !params[:version] %>
      <%= link_to "Previous version", {:version => (params[:version] || @versions.length).to_i - 1}%>
      <br>
    <% end %>
    <% if params[:version] %>
      <h3>This is <%= "#{params[:version]}"%> version</h3>

      <b>Modify at:</b>
      <%= @versions[(params[:version].to_i - 1)].created_at %>
      <br>
      <b>Admin</b>:
      <%= AdminUser.find(@versions[(params[:version].to_i - 1)].whodunnit).email %>
      <br>

      <%= link_to "Go to current version"%>
    <% end %>
  <% end %>
<% else %>
  <p>This item does not have any registered version.</p>
<% end %>
```

### Adding a history page.
you can add it by including a member action. like this
in 
`admin/posts.rb`
add
```ruby
...
  member_action :history do
    @post = Post.find(params[:id])
    # @versions = @post.versions # <-- Sadly, versions aren't available in this scope, so use:
    @versions = PaperTrail::Version.where(item_type: 'Post', item_id: @post.id)
    render "layouts/history"
  end
...
```
Then create the file
`app/views/layouts/history.html.arb`
with
```ruby
panel "History" do
  table_for assigns[:versions] do
    column ("Item") do |v| 
      if v.item
        link_to v.item.id, [:admin, v.item]
      end
    end      
    column ("Type") { |v| v.item_type.underscore.humanize }
    column ("Modified at") { |v| v.created_at.to_s :long }
    column ("Admin") { |v| link_to AdminUser.find(v.whodunnit).email, [:admin, AdminUser.find(v.whodunnit)] }
  end
end
```

Visit `/admin/post/:id/history` to see history for a particular post.
